package com.xyht.medicine_management_system.modules.coupon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.medicine_management_system.common.commonReturn.CommonCodeEnum;
import com.xyht.medicine_management_system.common.commonReturn.CommonResult;
import com.xyht.medicine_management_system.common.commonReturn.ResponseResult;
import com.xyht.medicine_management_system.modules.coupon.constant.CouponConstant;
import com.xyht.medicine_management_system.modules.coupon.constant.UserCouponRelationConstant;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsCoupon;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsUserCouponRelation;
import com.xyht.medicine_management_system.modules.coupon.entity.req.MmsUserCouponRelationReq;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsCouponResp;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsUserCouponRelationResp;
import com.xyht.medicine_management_system.modules.coupon.mapper.MmsCouponMapper;
import com.xyht.medicine_management_system.modules.coupon.mapper.MmsUserCouponRelationMapper;
import com.xyht.medicine_management_system.modules.coupon.service.MmsUserCouponRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;

/**
 * <p>
 * 优惠劵表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-12-03
 */
@Service
public class MmsUserCouponRelationServiceImpl extends ServiceImpl<MmsUserCouponRelationMapper, MmsUserCouponRelation> implements MmsUserCouponRelationService {
    @Resource
    private MmsCouponMapper mmsCouponMapper;

    @Override
    @Transactional
    public ResponseResult getCoupon(MmsUserCouponRelationReq userCouponRelation, String userId) {
        if (isNullOrEmpty(userCouponRelation.getCouponId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        MmsCoupon coupon = mmsCouponMapper.selectById(userCouponRelation.getCouponId());
        if (isNullOrEmpty(coupon)) {
            return CommonResult.failed(CommonCodeEnum.COUPON_NOT_EXIST);
        }

        //校验本优惠券是否已拥有
        int userOwnedCount = this.count(new LambdaQueryWrapper<MmsUserCouponRelation>()
                .eq(MmsUserCouponRelation::getCouponId, coupon.getId())
                .eq(MmsUserCouponRelation::getUserId, userId));
        if (userOwnedCount >= coupon.getUsageLimit()) {
            return CommonResult.failed(CommonCodeEnum.COUPON_ALREADY_OWNED);
        }

        Date nowDate = new Date();
        if (nowDate.before(coupon.getStartDate()) || nowDate.after(coupon.getEndDate())) {
            return CommonResult.failed(CommonCodeEnum.COUPON_TIME_INVALID);
        }

        //修改优惠券库存
        if (!isNullOrEmpty(coupon.getReceiveLimit())) {
            int receiveLimit = coupon.getReceiveLimit();
            //校验优惠券库存
            if (receiveLimit <= 0) {
                return CommonResult.failed(CommonCodeEnum.COUPON_OUT_OF_STOCK);
            }
            coupon.setReceiveLimit(receiveLimit - 1);
            int updNum = mmsCouponMapper.updateById(coupon);
            if (updNum == 0) {
                return CommonResult.failed(CommonCodeEnum.COUPON_GET_COUPON_FAIL);
            }
        }

        //新增本人优惠券
        MmsUserCouponRelation newUserCoupon = new MmsUserCouponRelation();
        newUserCoupon.setCouponId(coupon.getId());
        newUserCoupon.setUserId(userId);
        newUserCoupon.setIsUse(UserCouponRelationConstant.USER_COUPON_RELATION_NOT_USE);
        this.save(newUserCoupon);

        return CommonResult.success();
    }

    @Override
    public ResponseResult getCouponList(Integer pageNum, Integer pageSize, Integer status, String searchStr, String userId) {
        LambdaQueryWrapper<MmsUserCouponRelation> queryWrapper = new LambdaQueryWrapper<MmsUserCouponRelation>()
                .eq(MmsUserCouponRelation::getUserId, userId)
                .orderByDesc(MmsUserCouponRelation::getCreateTime);

        // 优惠券状态
        if (!isNullOrEmpty(status)) {
            if (status != 0 && status != 1 && status != 2) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        // 0.可使用 1.已使用 2.已失效
        Date nowDate = new Date(); // 当前时间
        if (status != null) {
            switch (status) {
                case 0: // 可使用
                    queryWrapper.eq(MmsUserCouponRelation::getIsUse, UserCouponRelationConstant.USER_COUPON_RELATION_NOT_USE); // 未使用
                    List<MmsCoupon> couponList = mmsCouponMapper.selectList(new LambdaQueryWrapper<MmsCoupon>()
                            .eq(MmsCoupon::getStatus, CouponConstant.COUPON_STATUS_AVAILABLE) // 优惠券可用
                            .le(MmsCoupon::getStartDate, nowDate)
                            .ge(MmsCoupon::getEndDate, nowDate));
                    List<String> couponIdList = couponList.stream().map(MmsCoupon::getId).distinct().collect(Collectors.toList());
                    queryWrapper.in(MmsUserCouponRelation::getCouponId, couponIdList.isEmpty() ? new ArrayList<>() : couponIdList);
                    break;
                case 1: // 已使用
                    queryWrapper.eq(MmsUserCouponRelation::getIsUse, UserCouponRelationConstant.USER_COUPON_RELATION_IS_USE); // 已使用
                    break;
                case 2: // 已失效
                    List<MmsCoupon> couponNotAvailebleList = mmsCouponMapper.selectList(new LambdaQueryWrapper<MmsCoupon>()
                            .eq(MmsCoupon::getStatus, CouponConstant.COUPON_STATUS_NOT_AVAILABLE) // 优惠券不可用
                            .or()
                            .le(MmsCoupon::getEndDate, nowDate));
                    List<String> notAvailebleCouponIdList = couponNotAvailebleList.stream().map(MmsCoupon::getId).distinct().collect(Collectors.toList());
                    queryWrapper.in(MmsUserCouponRelation::getCouponId, notAvailebleCouponIdList.isEmpty() ? new ArrayList<>() : notAvailebleCouponIdList);
                    break;
            }
        }

        if (!isNullOrEmpty(searchStr)) {
            StringUtils.deleteWhitespace(searchStr);
            List<MmsCoupon> searchStrCouponList = mmsCouponMapper.selectList(new LambdaQueryWrapper<MmsCoupon>()
                    .and(i -> i.like(MmsCoupon::getName, searchStr).or()
                            .like(MmsCoupon::getNote, searchStr)));
            List<String> searchStrCouponIdList = searchStrCouponList.stream().map(MmsCoupon::getId).distinct().collect(Collectors.toList());
            queryWrapper.in(MmsUserCouponRelation::getCouponId, searchStrCouponIdList.isEmpty() ? new ArrayList<>() : searchStrCouponIdList);
        }

        Page<MmsUserCouponRelation> page = new Page<>(pageNum, pageSize);
        this.page(page, queryWrapper);

        List<MmsUserCouponRelationResp> userCouponRespList = page.getRecords().stream().map(userCoupon -> {
            MmsUserCouponRelationResp userCouponResp = new MmsUserCouponRelationResp();
            BeanUtils.copyProperties(userCoupon, userCouponResp);

            //优惠券详情
            MmsCoupon coupon = mmsCouponMapper.selectById(userCoupon.getCouponId());
            if (!isNullOrEmpty(coupon)) {
                MmsCouponResp couponResp = new MmsCouponResp();
                BeanUtils.copyProperties(coupon, couponResp);
                userCouponResp.setCouponInfo(couponResp);
            }

            return userCouponResp;
        }).collect(Collectors.toList());

        return CommonResult.success(userCouponRespList, (int) page.getTotal());
    }
}
